package com.q3d.demo.svc.hello.grpc.service;

import java.util.ArrayList;

import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;

import com.q3d.demo.api.hello.grpc.HelloWorldGrpcP1K2;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcP1List;
import com.q3d.demo.api.hello.grpc.UuidGrpc;
import com.q3d.demo.api.hello.grpc.UuidListGrpc;
import com.q3d.demo.common.lib.service.dto.CountResultDto;
import com.q3d.demo.common.lib.service.dto.IdExtDto;
import com.q3d.demo.common.lib.service.dto.IdExtListDto;
import com.q3d.demo.common.lib.service.dto.OpResultDto;
import com.q3d.demo.common.lib.service.dto.PageRequestDto;
import com.q3d.demo.common.lib.service.dto.UuidDto;
import com.q3d.demo.common.lib.service.dto.UuidListDto;
import com.q3d.demo.svc.hello.mybatis.service.HelloWorldServiceBatis;
import com.q3d.demo.api.hello.grpc.IdExtGrpc;
import com.q3d.demo.api.hello.grpc.IdExtListGrpc;
import com.q3d.demo.api.hello.grpc.CountResultGrpc;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcP1;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcP1K1;
import com.q3d.demo.api.hello.grpc.OpResultGrpc;
import com.q3d.demo.api.hello.grpc.StringGrpc;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcR1K1;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcR1K1List;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcR1K2;
import com.q3d.demo.api.hello.grpc.HelloWorldGrpcR1K2List;
import com.q3d.demo.api.hello.grpc.HelloWorldServiceGrpc;
import com.q3d.demo.api.hello.grpc.PageRequestGrpc;
import com.q3d.demo.api.hello.dto.HelloWorldP1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1K1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1K2Dto;
import com.q3d.demo.api.hello.dto.HelloWorldP1ListDto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K1Dto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K1ListDto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K2Dto;
import com.q3d.demo.api.hello.dto.HelloWorldR1K2ListDto;

import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;

@SuppressWarnings(value = "unused") /** 暂时忽略 Logger 工具没有在使用的 Warning */
@GrpcService /** 声明自己为 gRPC 服务 */
@Slf4j /** Lombok 的 Logger 注解 */
/**
 * 继承 protoc 生成的基础类，实现具体功能
 * 
 * @author 叶湘 ( weixin:yexiang841, email:yexiang841@qq.com )
 */
public class HelloWorldGrpcService extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {

    @Autowired
    protected HelloWorldServiceBatis helloWorldService;

    @Autowired
    protected ModelMapper modelMapper;

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void hello(StringGrpc grpcStringRequest,
            io.grpc.stub.StreamObserver<StringGrpc> responseObserver) {
        StringGrpc grpcStringResponse = StringGrpc.newBuilder()
                .setText(">>>> Hello " + grpcStringRequest.getText() + " <<<<").build();
        responseObserver.onNext(grpcStringResponse);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void addOne(HelloWorldGrpcP1 grpcP1,
            io.grpc.stub.StreamObserver<UuidGrpc> responseObserver) {
        HelloWorldP1Dto dtoP1 = modelMapper.map(grpcP1, HelloWorldP1Dto.class);
        UuidDto dtoUuid = helloWorldService.addOne(dtoP1);
        UuidGrpc grpcUuid = UuidGrpc.newBuilder().setUuid(dtoUuid.getUuid()).build();
        responseObserver.onNext(grpcUuid);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void addBatch(HelloWorldGrpcP1List grpcP1List,
            io.grpc.stub.StreamObserver<UuidListGrpc> responseObserver) {
        HelloWorldP1ListDto dtoP1List = HelloWorldP1ListDto.builder()
                .dtoList(new ArrayList<HelloWorldP1Dto>(grpcP1List.getGrpcCount()))
                .build();
        for (HelloWorldGrpcP1 grpcP1 : grpcP1List.getGrpcList()) {
            HelloWorldP1Dto dtoP1 = modelMapper.map(grpcP1, HelloWorldP1Dto.class);
            dtoP1List.getDtoList().add(dtoP1);
        }
        UuidListDto dtoUuidList = helloWorldService.addBatch(dtoP1List);
        UuidListGrpc.Builder grpcUuidListBuilder = UuidListGrpc.newBuilder();
        for (UuidDto dtoUuid : dtoUuidList.getDtoList()) {
            UuidGrpc grpcUuid = UuidGrpc.newBuilder().setUuid(dtoUuid.getUuid()).build();
            grpcUuidListBuilder.addGrpc(grpcUuid);
        }
        responseObserver.onNext(grpcUuidListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void removeOne(UuidGrpc grpcUuid,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        UuidDto dtoUuid = modelMapper.map(grpcUuid, UuidDto.class);
        OpResultDto dtoOpResult = helloWorldService.removeOne(dtoUuid);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void removeBatch(UuidListGrpc grpcUuidList,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        UuidListDto dtoUuidList = UuidListDto.builder()
                .dtoList(new ArrayList<UuidDto>(grpcUuidList.getGrpcCount())).build();
        for (UuidGrpc grpcUuid : grpcUuidList.getGrpcList()) {
            UuidDto dtoUuid = modelMapper.map(grpcUuid, UuidDto.class);
            dtoUuidList.getDtoList().add(dtoUuid);
        }
        OpResultDto dtoOpResult = helloWorldService.removeBatch(dtoUuidList);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void deleteOne(IdExtGrpc grpcIdExt,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
        OpResultDto dtoOpResult = helloWorldService.deleteOne(dtoIdExt);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void deleteBatch(IdExtListGrpc grpcIdExtList,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        IdExtListDto dtoIdExtList = IdExtListDto.builder()
                .dtoList(new ArrayList<IdExtDto>(grpcIdExtList.getGrpcCount())).build();
        for (IdExtGrpc grpcIdExt : grpcIdExtList.getGrpcList()) {
            IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
            dtoIdExtList.getDtoList().add(dtoIdExt);
        }
        OpResultDto dtoOpResult = helloWorldService.deleteBatch(dtoIdExtList);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void reviveOne(IdExtGrpc grpcIdExt,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
        OpResultDto dtoOpResult = helloWorldService.reviveOne(dtoIdExt);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void reviveBatch(IdExtListGrpc grpcIdExtList,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        IdExtListDto dtoIdExtList = IdExtListDto.builder()
                .dtoList(new ArrayList<IdExtDto>(grpcIdExtList.getGrpcCount())).build();
        for (IdExtGrpc grpcIdExt : grpcIdExtList.getGrpcList()) {
            IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
            dtoIdExtList.getDtoList().add(dtoIdExt);
        }
        OpResultDto dtoOpResult = helloWorldService.reviveBatch(dtoIdExtList);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void editSelective(HelloWorldGrpcP1K1 grpcP1K1,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        HelloWorldP1K1Dto dtoP1K1 = modelMapper.map(grpcP1K1, HelloWorldP1K1Dto.class);
        OpResultDto dtoOpResult = helloWorldService.editSelective(dtoP1K1);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void updateSelective(HelloWorldGrpcP1K2 grpcP1K2,
            io.grpc.stub.StreamObserver<OpResultGrpc> responseObserver) {
        HelloWorldP1K2Dto dtoP1K2 = modelMapper.map(grpcP1K2, HelloWorldP1K2Dto.class);
        OpResultDto dtoOpResult = helloWorldService.updateSelective(dtoP1K2);
        OpResultGrpc grpcOpResult = OpResultGrpc.newBuilder().setOpResult(dtoOpResult.getOpResult()).build();
        responseObserver.onNext(grpcOpResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void getCount(com.google.protobuf.Empty request,
            io.grpc.stub.StreamObserver<CountResultGrpc> responseObserver) {
        CountResultDto dtoCountResult = helloWorldService.getCount();
        CountResultGrpc grpcCountResult = CountResultGrpc.newBuilder().setCountResult(dtoCountResult.getCountResult())
                .build();
        responseObserver.onNext(grpcCountResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void getOne(UuidGrpc grpcUuid,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K1> responseObserver) {
        UuidDto dtoUuid = modelMapper.map(grpcUuid, UuidDto.class);
        HelloWorldR1K1Dto dtoR1K1 = helloWorldService.getOne(dtoUuid);
        HelloWorldGrpcR1K1 grpcR1K1 = modelMapper.map(dtoR1K1, HelloWorldGrpcR1K1.Builder.class).build();
        responseObserver.onNext(grpcR1K1);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void getBatch(UuidListGrpc grpcUuidList,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K1List> responseObserver) {
        UuidListDto dtoUuidList = UuidListDto.builder()
                .dtoList(new ArrayList<UuidDto>(grpcUuidList.getGrpcCount())).build();
        for (UuidGrpc grpcUuid : grpcUuidList.getGrpcList()) {
            UuidDto dtoUuid = modelMapper.map(grpcUuid, UuidDto.class);
            dtoUuidList.getDtoList().add(dtoUuid);
        }
        HelloWorldR1K1ListDto dtoR1K1List = helloWorldService.getBatch(dtoUuidList);
        HelloWorldGrpcR1K1List.Builder grpcR1K1ListBuilder = HelloWorldGrpcR1K1List.newBuilder();
        for (HelloWorldR1K1Dto dtoR1K1 : dtoR1K1List.getDtoList()) {
            HelloWorldGrpcR1K1 grpcR1K1 = modelMapper.map(dtoR1K1, HelloWorldGrpcR1K1.Builder.class).build();
            grpcR1K1ListBuilder.addGrpc(grpcR1K1);
        }
        responseObserver.onNext(grpcR1K1ListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void getByPage(PageRequestGrpc grpcPageRequest,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K1List> responseObserver) {
        PageRequestDto dtoPageRequest = PageRequestDto.builder()
                .page(grpcPageRequest.getPage())
                .limit(grpcPageRequest.getLimit())
                .build();
        HelloWorldR1K1ListDto dtoR1K1List = helloWorldService.getByPage(dtoPageRequest);
        HelloWorldGrpcR1K1List.Builder grpcR1K1ListBuilder = HelloWorldGrpcR1K1List.newBuilder();
        for (HelloWorldR1K1Dto dtoR1K1 : dtoR1K1List.getDtoList()) {
            HelloWorldGrpcR1K1 grpcR1K1 = modelMapper.map(dtoR1K1, HelloWorldGrpcR1K1.Builder.class).build();
            grpcR1K1ListBuilder.addGrpc(grpcR1K1);
        }
        responseObserver.onNext(grpcR1K1ListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void getUuidByPage(PageRequestGrpc grpcPageRequest,
            io.grpc.stub.StreamObserver<UuidListGrpc> responseObserver) {
        PageRequestDto dtoPageRequest = PageRequestDto.builder()
                .page(grpcPageRequest.getPage())
                .limit(grpcPageRequest.getLimit())
                .build();
        UuidListDto dtoUuidList = helloWorldService.getUuidByPage(dtoPageRequest);
        UuidListGrpc.Builder grpcUuidListBuilder = UuidListGrpc.newBuilder();
        for (UuidDto dtoUuid : dtoUuidList.getDtoList()) {
            UuidGrpc grpcUuid = UuidGrpc.newBuilder().setUuid(dtoUuid.getUuid()).build();
            grpcUuidListBuilder.addGrpc(grpcUuid);
        }
        responseObserver.onNext(grpcUuidListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectCount(com.google.protobuf.Empty request,
            io.grpc.stub.StreamObserver<CountResultGrpc> responseObserver) {
        CountResultDto dtoCountResult = helloWorldService.selectCount();
        CountResultGrpc grpcCountResult = CountResultGrpc.newBuilder().setCountResult(dtoCountResult.getCountResult())
                .build();
        responseObserver.onNext(grpcCountResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectCountRemoved(com.google.protobuf.Empty request,
            io.grpc.stub.StreamObserver<CountResultGrpc> responseObserver) {
        CountResultDto dtoCountResult = helloWorldService.selectCountRemoved();
        CountResultGrpc grpcCountResult = CountResultGrpc.newBuilder().setCountResult(dtoCountResult.getCountResult())
                .build();
        responseObserver.onNext(grpcCountResult);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectOne(IdExtGrpc grpcIdExt,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K2> responseObserver) {
        IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
        HelloWorldR1K2Dto dtoR1K2 = helloWorldService.selectOne(dtoIdExt);
        HelloWorldGrpcR1K2 grpcR1K2 = modelMapper.map(dtoR1K2, HelloWorldGrpcR1K2.Builder.class).build();
        responseObserver.onNext(grpcR1K2);
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectBatch(IdExtListGrpc grpcIdExtList,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K2List> responseObserver) {
        IdExtListDto dtoIdExtList = IdExtListDto.builder()
                .dtoList(new ArrayList<IdExtDto>(grpcIdExtList.getGrpcCount())).build();
        for (IdExtGrpc grpcIdExt : grpcIdExtList.getGrpcList()) {
            IdExtDto dtoIdExt = modelMapper.map(grpcIdExt, IdExtDto.class);
            dtoIdExtList.getDtoList().add(dtoIdExt);
        }
        HelloWorldR1K2ListDto dtoR1K2List = helloWorldService.selectBatch(dtoIdExtList);
        HelloWorldGrpcR1K2List.Builder grpcR1K2ListBuilder = HelloWorldGrpcR1K2List.newBuilder();
        for (HelloWorldR1K2Dto dtoR1K2 : dtoR1K2List.getDtoList()) {
            HelloWorldGrpcR1K2 grpcR1K2 = modelMapper.map(dtoR1K2, HelloWorldGrpcR1K2.Builder.class).build();
            grpcR1K2ListBuilder.addGrpc(grpcR1K2);
        }
        responseObserver.onNext(grpcR1K2ListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectByPage(PageRequestGrpc grpcPageRequest,
            io.grpc.stub.StreamObserver<HelloWorldGrpcR1K2List> responseObserver) {
        PageRequestDto dtoPageRequest = PageRequestDto.builder()
                .page(grpcPageRequest.getPage())
                .limit(grpcPageRequest.getLimit())
                .build();
        HelloWorldR1K2ListDto dtoR1K2List = helloWorldService.selectByPage(dtoPageRequest);
        HelloWorldGrpcR1K2List.Builder grpcR1K2ListBuilder = HelloWorldGrpcR1K2List.newBuilder();
        for (HelloWorldR1K2Dto dtoR1K2 : dtoR1K2List.getDtoList()) {
            HelloWorldGrpcR1K2 grpcR1K2 = modelMapper.map(dtoR1K2, HelloWorldGrpcR1K2.Builder.class).build();
            grpcR1K2ListBuilder.addGrpc(grpcR1K2);
        }
        responseObserver.onNext(grpcR1K2ListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectIdExtByPage(PageRequestGrpc grpcPageRequest,
            io.grpc.stub.StreamObserver<IdExtListGrpc> responseObserver) {
        PageRequestDto dtoPageRequest = PageRequestDto.builder()
                .page(grpcPageRequest.getPage())
                .limit(grpcPageRequest.getLimit())
                .build();
        IdExtListDto dtoIdExtList = helloWorldService.selectIdExtByPage(dtoPageRequest);
        IdExtListGrpc.Builder grpcIdExtListBuilder = IdExtListGrpc.newBuilder();
        for (IdExtDto dtoIdExt : dtoIdExtList.getDtoList()) {
            IdExtGrpc grpcIdExt = IdExtGrpc.newBuilder().setIdExt(dtoIdExt.getIdExt()).build();
            grpcIdExtListBuilder.addGrpc(grpcIdExt);
        }
        responseObserver.onNext(grpcIdExtListBuilder.build());
        responseObserver.onCompleted();
    }

    @Override /** 重写 proto 文件中声明后自动生成的方法 */
    public void selectIdExtRemoved(com.google.protobuf.Empty request,
            io.grpc.stub.StreamObserver<IdExtListGrpc> responseObserver) {
        IdExtListDto dtoIdExtList = helloWorldService.selectIdExtRemoved();
        IdExtListGrpc.Builder grpcIdExtListBuilder = IdExtListGrpc.newBuilder();
        for (IdExtDto dtoIdExt : dtoIdExtList.getDtoList()) {
            IdExtGrpc grpcIdExt = IdExtGrpc.newBuilder().setIdExt(dtoIdExt.getIdExt()).build();
            grpcIdExtListBuilder.addGrpc(grpcIdExt);
        }
        responseObserver.onNext(grpcIdExtListBuilder.build());
        responseObserver.onCompleted();
    }

}
